<template>
  <!-- 圆点提示 -->
  <van-button
    v-if="shell=='badge'"
    :class="buttonClass"
    :Style="buttonStyle"
    :type="elType"
    :round="round"
    :size="small?'mini':'small'"
    :icon="circleIcon"
    :disabled="disabled"
    @click="submitClick"
  >
    <slot v-if="!circle||type=='text'"></slot>
    <div :class="badgeOption?'badge-info':'badge-info badge-dot'">{{badgeOption?badgeOption:null}}</div>
  </van-button>

  <!-- 下拉菜单 -->
  <div v-else-if="shell=='dropdown'">
    <van-button
      :class="buttonClass"
      :Style="buttonStyle"
      :type="elType"
      :round="round"
      :size="small?'mini':'small'"
      :icon="circleIcon"
      :disabled="disabled"
      @click="showMenu=true"
    >
      <slot v-if="!circle||type=='text'"></slot>
    </van-button>
    <van-action-sheet
      v-model="showMenu"
      :actions="dropdownArray"
      close-on-popstate
      @select="dropdownClick"
    />
  </div>

  <!-- 弹出菜单 -->
  <div v-else-if="shell=='popup'">
    <van-button
      :class="buttonClass"
      :Style="buttonStyle"
      :type="elType"
      :round="round"
      :size="small?'mini':'small'"
      :icon="circleIcon"
      :disabled="disabled"
      @click="showMenu=true"
    >
      <slot v-if="!circle||type=='text'"></slot>
    </van-button>
    <van-popup v-model="showMenu" close-on-popstate @click="popClick">
      <slot name="popup"></slot>
    </van-popup>
  </div>

  <!-- 预览 -->
  <van-button
    v-else-if="shell=='preview'"
    :class="buttonClass"
    :Style="buttonStyle"
    :type="elType"
    :round="round"
    :size="small?'mini':'small'"
    :icon="circleIcon"
    :disabled="disabled"
    @click="previewClick"
  >
    <slot v-if="!circle||type=='text'"></slot>
  </van-button>

  <!-- 上传 -->
  <div v-else-if="shell=='upload'" class="upload-bar">
    <van-button
      :class="buttonClass"
      :Style="buttonStyle"
      :type="elType"
      :round="round"
      :size="small?'mini':'small'"
      :icon="circleIcon"
      :disabled="disabled"
    >
      <slot v-if="!circle||type=='text'"></slot>
    </van-button>
    <input
      class="upload-input"
      ref="upload"
      type="file"
      :accept="uploadAccept"
      :multiple="uploadMaxcount>1"
      @change="uploadClick"
      :disabled="disabled"
    />
  </div>

  <!-- 选择位置 -->
  <div v-else-if="shell=='mapchoose'">
    <van-button
      :class="buttonClass"
      :Style="buttonStyle"
      :type="elType"
      :round="round"
      :size="small?'mini':'small'"
      :icon="circleIcon"
      :disabled="disabled"
      @click="showMenu=true"
    >
      <slot v-if="!circle||type=='text'"></slot>
    </van-button>
    <van-popup
      v-model="showMenu"
      position="bottom"
      round
      closeable
      close-on-popstate
      @open="openMapchoose"
      @close="closeMapchoose"
    >
      <iframe
        id="mapId"
        style="padding-top:40px;"
        :width="mapWidth+'px'"
        :height="(mapHeight-50)+'px'"
        frameborder="0"
        @load="mapLoad"
        :src="mapUrl"
      ></iframe>
    </van-popup>
  </div>

  <!-- 显示位置 -->
  <div v-else-if="shell=='maplocation'">
    <van-button
      :class="buttonClass"
      :Style="buttonStyle"
      :type="elType"
      :round="round"
      :size="small?'mini':'small'"
      :icon="circleIcon"
      :disabled="disabled"
      @click="showMenu=true"
    >
      <slot v-if="!circle||type=='text'"></slot>
    </van-button>
    <van-popup v-model="showMenu" position="bottom" round closeable close-on-popstate>
      <iframe
        style="padding-top:40px;"
        :width="mapWidth+'px'"
        :height="(mapHeight-50)+'px'"
        frameborder="0"
        :src="mapUrl"
      ></iframe>
    </van-popup>
  </div>

  <!-- 单个按钮 -->
  <van-button
    v-else
    :class="buttonClass"
    :Style="buttonStyle"
    :type="elType"
    :round="round"
    :size="small?'mini':'small'"
    :icon="circleIcon"
    :disabled="disabled"
    @click="submitClick"
  >
    <slot v-if="!circle||type=='text'"></slot>
  </van-button>
</template>

<script>
import api from "@/api/api";
import { Button, ImagePreview, ActionSheet, Popup } from "vant";
export default {
  components: {
    "van-button": Button,
    "van-action-sheet": ActionSheet,
    "van-popup": Popup
  },

  props: {
    buttonStyle: {// 按钮样式
      type: String,
      default: null
    },

    type: {// 按钮类型：edit、delete、cancel、search、text
      type: String,
      default: "edit"
    },

    small: {// 是否是小号按钮
      type: Boolean,
      default: false
    },

    round: {// 是否是圆角
      type: Boolean,
      default: false
    },

    circle: {// 是否是圆形，设置文字会被禁用
      type: Boolean,
      default: false
    },

    shell: {// 外壳类型：badge、dropdown、popup、preview、upload、mapchoose、maplocation
      type: String,
      default: null
    },

    badgeOption: {// 对应badge的圆点提示文字，不为空则显示文字，为空则显示圆点
      type: String,
      default: null
    },

    dropdownOption: {// 对应dropdown的下拉菜单数组
      type: Array,
      default: null
    },

    previewIndex: {// 对应preview的图片url数组的index
      type: Number,
      default: 0
    },

    previewOption: {// 对应preview的图片url数组
      type: Array,
      default: null
    },

    uploadType: {// 对应upload，文件可选的类型：jpg|jpeg|png|gif|zip|excel
      type: String,
      default: null
    },

    uploadAccept: {// 对应upload，文件选择的范围：image/*、video/*、audio/*
      type: String,
      default: null
    },

    uploadMaxcount: {// 对应upload，文件可选的的最大个数
      type: Number,
      default: 1
    },

    uploadMaxsize: {// 对应upload，选中单个文件的最大大小
      type: Number,
      default: 0
    },

    mapLongitude: {// 对应mapchoose、maplocation的经度
      type: [Number, String],
      default: null
    },

    mapLatitude: {// 对应mapchoose、maplocation的纬度
      type: [Number, String],
      default: null
    },

    maplocationName: {// 对应maplocation的标注名称
      type: String,
      default: null
    },

    disabled: {// 是否不可用
      type: Boolean,
      default: false
    }
  },

  data() {
    return {
      showMenu: false,
      mapWidth: document.body.clientWidth,
      mapHeight: document.body.clientHeight
    }
  },

  computed: {
    elType() {
      if (this.type == "delete") {
        return "danger";
      }
      if (this.type == "cancel") {
        return "default";
      }
      if (this.type == "search") {
        return "info";
      }
      if (this.type == "text") {
        return "default";
      }
      return "info";
    },

    buttonClass() {
      if (this.type == "text") {
        return "text-button";
      }
      if (this.circle) {
        if (this.small) {
          return "circle-button circle-button2";
        }
        return "circle-button";
      }
      return null;
    },

    circleIcon() {
      if (this.type == "search") {
        return "search";
      }
      if (this.circle) {
        if (this.type == "edit") {
          return "edit";
        }
        if (this.type == "delete") {
          return "delete";
        }
        if (this.type == "cancel") {
          return "close";
        }
      }
      return null;
    },

    dropdownArray() {
      if (this.shell == "dropdown") {
        if (this.dropdownOption) {
          return this.dropdownOption.map(item => {
            return {
              name: item
            };
          });
        }
      }
      return null;
    },

    mapUrl() {
      if (this.shell == "mapchoose") {
        let url = "https://m.amap.com/picker/?key=" + api.getAppConfig().getMapKey();
        if (this.mapLongitude && this.mapLatitude) {
          url += "&center=" + this.mapLongitude + "," + this.mapLatitude;
        }
        return url;
      }
      if (this.shell == "maplocation") {
        let url = "https://m.amap.com/navi/?hideRouteIcon=1&key=" + api.getAppConfig().getMapKey();
        if (this.mapLongitude && this.mapLatitude) {
          url += "&dest=" + this.mapLongitude + "," + this.mapLatitude;
        }
        if (this.maplocationName) {
          url += "&destName=" + this.maplocationName;
        }
        return url;
      }
      return null;
    }
  },

  methods: {
    submitClick() {
      this.$emit("click");
    },

    dropdownClick(item, index) {
      this.$emit("click", item.name, index);
      this.showMenu = false;
    },

    popClick() {
      this.$emit("click", this.popCloseClick);
    },

    popCloseClick() {
      this.showMenu = false;
    },

    previewClick() {
      ImagePreview({
        startPosition: this.previewIndex,
        images: this.previewOption
      });
    },

    uploadClick(e) {
      if (e.target && this.checkFiles(e.target.files)) {
        if (e.target.files.length == 1) {
          this.$emit("click", e.target.files[0]);
        } else {
          this.$emit("click", e.target.files);
        }
      } else {
        this.$emit("click");
      }
      this.$refs.upload.value = "";
    },

    checkFiles(files) {
      if (!files || files.length < 1) {
        return false;
      }
      if (this.uploadMaxcount > 0 && files.length > this.uploadMaxcount) {
        api.toast("选择的文件不能超过" + this.uploadMaxcount + "个");
        return false;
      }
      for (let i = 0; i < files.length; i++) {
        let file = files[i];
        let typeError = this.checkFileType(file.type);
        if (typeError) {
          api.toast(typeError);
          return false;
        }
        if (this.uploadMaxsize > 0 && file.size > this.uploadMaxsize) {
          let size = this.uploadMaxsize > 1048576 ? this.uploadMaxsize / 1048576 + "M" : this.uploadMaxsize / 1024 + "KB";
          api.toast("选择的文件大小不能超过" + size);
          return false;
        }
      }
      return true;
    },

    checkFileType(type) {
      if (!this.uploadType) {
        return null;
      }
      if (!type) {
        return "选择的文件类型未知";
      }
      let typeArray = this.uploadType.split("|");
      let error = null;
      for (let i = 0; i < typeArray.length; i++) {
        let item = typeArray[i].trim();
        if (type.indexOf(item) > -1) {
          return null;
        }
        if (!error) {
          error = item;
        } else {
          error += "、" + item;
        }
      }
      return "请选择" + error + "类型的文件";
    },

    mapListener(event) {
      if (event && event.data && event.data.name && event.data.address && event.data.location) {
        this.showMenu = false;
        let param = {
          name: event.data.name,
          address: event.data.address
        };
        let array = event.data.location.split(",");
        if (array.length == 2) {
          param.longitude = array[0];
          param.latitude = array[1];
        }
        this.$emit("click", param);
      }
    },

    mapLoad(e) {
      document.getElementById("mapId").contentWindow.postMessage("hello", "https://m.amap.com/picker/");
    },

    openMapchoose() {
      window.addEventListener("message", this.mapListener, false);
    },

    closeMapchoose() {
      window.removeEventListener("message", this.mapListener, false);
    }
  }
}
</script>

<style scoped>
.circle-button {
  padding: 0;
  min-width: 0;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
}

.circle-button2 {
  width: 0.44rem;
  height: 0.44rem;
}

.text-button {
  padding: 0;
  min-width: 0;
  height: 100%;
  line-height: normal;
  border: none;
}

.text-button::before {
  display: none;
}

.badge-info {
  position: absolute;
  top: 0;
  right: 0;
  box-sizing: border-box;
  min-width: 16px;
  padding: 0 3px;
  color: #fff;
  font-weight: 500;
  font-size: 12px;
  font-family: PingFang SC, Helvetica Neue, Arial, sans-serif;
  line-height: 14px;
  text-align: center;
  background-color: #ee0a24;
  border: 1px solid #fff;
  border-radius: 16px;
  -webkit-transform: translate(50%, -50%);
  transform: translate(50%, -50%);
  -webkit-transform-origin: 100%;
  transform-origin: 100%;
}

.badge-dot {
  width: 8px;
  min-width: 0;
  height: 8px;
  background-color: #ee0a24;
  border-radius: 100%;
}

.upload-bar {
  position: relative;
}

.upload-input {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
}
</style>